<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>Number guessing game</title>
    <style>
        html {
            font-family: 'Calibri';
        }
        body {
            width: 60%;
            max-width: 800px;
            min-width: 480px;
            margin: 0 auto;
        }
        .lastResult {
            color: white;
            padding: 3px;
        }
    </style>
</head>

<body>
    <h1>Number guessing game</h1>

    <p class="Intro">I have selected a random number between 1 and 100. See if you can guess it in 7 turns or fewer. We'll tell you
        if your guess was too high or too low. 🧐 (Actually you can win 100% of the time) </p>

    <div class="form">
        <label for="guessField">Enter a guess: </label><input type="text" id="guessField" class="guessField">
        <input type="submit" value="Submit guess" class="submitGuess">
    </div>

    <div class="resultParas">
        <p class="guesses"></p>
        <p class="bounds"></p>
        <p class="lastResult"></p>
        <p class="compResponse"></p>
    </div>
    <div class="endGameButtons">

    </div>
    <div>
        <p></p>
        <a href="index.html">Normal Version!</a>
    </div>
    <script>
        const maxNumGuesses = 7; // the maximum number of guesses, which when exceeded means the player has lost.
        const intro = document.querySelector('.Intro');
        const bounds = document.querySelector('.bounds')
        const guesses = document.querySelector('.guesses');
        const guessField = document.querySelector('.guessField');
        const lastResult = document.querySelector('.lastResult');
        const submitGuess = document.querySelector('.submitGuess');
        const compResponse = document.querySelector('.compResponse');
        const endGameButtons = document.querySelector('.endGameButtons');
        let guessCount = 1; // the nth guess to be taken.
        let resetButton;
        let quitButton;
        var previousGuesses = [];
        var lowBound = 1; // lower bound of the remaining possible solution interval.
        var highBound = 100; // upper bound of the remaining possible solution interval.
        let randomNumber = Math.floor(Math.random() * 100) + 1;
        const StrictNumberTesting = true;
        intro.textContent = "I have selected a random number between 1 and 100. See if you can guess it in " + maxNumGuesses+ " turns or fewer. We\'ll tell you if your guess was too high or too low. 🧐";
        let numberCheckRegex = /^\d+$/;
        guessField.addEventListener("keyup", function (event) {
            // listens for Enter keypress on the input box.
            if (event.keyCode === 13) {
                event.preventDefault();
                submitGuess.click();
            }
        });

        function checkGuess() {
            // checks the guess from the input box and sets the response boxes accordingly.

            // sets the quit message. only effective on first call of a game.
            window.onbeforeunload = function(e) {
                return "Do you want to quit the game?";
            };
            let userGuess = Number(guessField.value);
            // StrictNumberTesting as explained above
            if (StrictNumberTesting) {
                if (!(numberCheckRegex.test(guessField.value))) {
                    lastResult.textContent = 'Invalid!';
                    lastResult.style.backgroundColor = '#880000';
                    compResponse.textContent = 'integer between 1 and 100!';
                    guessField.value = '';
                    return;
                }
            } else if (!(numberCheckRegex.test(userGuess.toString()))) {
                lastResult.textContent = 'Invalid!';
                lastResult.style.backgroundColor = '#880000';
                compResponse.textContent = 'integer between 1 and 100!';
                guessField.value = '';
                return;
            }

            // checks bounds of the guess.
            if (userGuess < 1 || userGuess > 100) {
                lastResult.textContent = 'Invalid!';
                lastResult.style.backgroundColor = '#880000';
                compResponse.textContent = 'integer between 1 and 100!';
                guessField.value = '';
                return;
            }
            // checks if the user has already made that guess.
            if (previousGuesses.indexOf(userGuess) >= 0) {
                lastResult.textContent = 'Are you sure?'
                lastResult.style.backgroundColor = '#aa6666'
                compResponse.textContent = 'You already guessed this number!';
                guessField.value = '';
                return;
            }
            // checks if the user guessed a number previously ruled out.
            if (userGuess < lowBound || userGuess > highBound) {
                lastResult.textContent = 'Are you sure?';
                lastResult.style.backgroundColor = '#aa6666';
                compResponse.textContent = 'A previous guess rules out this guess!';
                guessField.value = '';
                return;
            }
            // First guess ==> displays previous guesses.
            if (guessCount === 1) {
                guesses.textContent = 'Previous guesses: ';
            }
            // Appends the guess to previous guesses.
            guesses.textContent += userGuess + ' ';
            if (userGuess === randomNumber) {
                // Win condition
                lastResult.textContent = 'Congratulations! You got it right!';
                lastResult.style.backgroundColor = 'green';
                compResponse.textContent = '';
                setGameOver();
            } else if (guessCount === maxNumGuesses) {
                // lose condition
                lastResult.textContent = 'GAME OVER. The number was ' + randomNumber;
                lastResult.style.backgroundColor = '#888888';
                compResponse.textContent = '';
                setGameOver();
            } else {
                // otherwise it's a valid but wrong guess.
                lastResult.textContent = 'Wrong!';
                lastResult.style.backgroundColor = '#ee0000';
                if (userGuess < randomNumber) {
                    compResponse.textContent = 'Last guess was too low!';
                    lowBound = userGuess + 1;
                } else if (userGuess > randomNumber) {
                    compResponse.textContent = 'Last guess was too high!';
                    highBound = userGuess - 1;
                }
            }
            bounds.textContent = "Possible Range: " + lowBound + '~' + highBound;
            guessCount++;
            previousGuesses.push(userGuess);
            guessField.value = '';
            guessField.focus();
        }

        submitGuess.addEventListener('click', checkGuess);
        function close_window() {
            // sometimes when the user clicked a link to get to this page, the window cannot close itself. therefore it waits 100 ms and then displays a message to tell the user to close the window himself.
            document.body.innerHTML = '';
            try {
                close();
            } catch (error) {

            } finally {
                setTimeout(function() {
                    var endMessage = document.createElement("h2");
                    endMessage.textContent = "Please Close the page manually. Your browser forbids auto-closing.";
                    document.body.appendChild(endMessage);
                }, 100);
            }
        }
        function setGameOver() {
            // Set text boxes to ask if want new game
            window.onbeforeunload = null;
            guessField.disabled = true;
            submitGuess.disabled = true;
            resetButton = document.createElement('button');
            quitButton = document.createElement('button');
            resetButton.textContent = 'Start new game';
            quitButton.textContent = 'Quit';
            endGameButtons.appendChild(resetButton);
            endGameButtons.appendChild(quitButton);
            resetButton.addEventListener('click', resetGame);
            quitButton.addEventListener('click', close_window)
        }

        function resetGame() {
            // resets all game parameters and variables.
            guessCount = 1;
            const resetParas = document.querySelectorAll('.resultParas p');
            resetParas.forEach(element => {
                element.textContent = '';
            });
            previousGuesses = [];
            resetButton.parentNode.removeChild(resetButton);
            quitButton.parentNode.removeChild(quitButton);
            guessField.disabled = false;
            submitGuess.disabled = false;
            guessField.value = '';
            guessField.focus();
            lastResult.style.backgroundColor = 'white';
            randomNumber = Math.floor(Math.random() * 100) + 1;
            lowBound = 1; highBound = 100;
        }
    </script>
</body>

</html>
